<?php

/**
 * Class UrlRule
 * @author Brian Nguyen <thuann89@gmail.com>
 * @version 1.0
 * UrlRule is a property of webmaster, all right reserved.
 */
class UrlRule extends CUrlRule
{

    /**
     * @var string name of table languages
     */
    public $langTable = 'tbl_language';

    /**
     * @var string replacement name of language in rules
     */
    public $langExp = 'lang';

    /**
     * Constructor.
     * @param string $route the route of the URL (controller/action)
     * @param string $pattern the pattern for matching the URL
     */
    public function __construct($route, $pattern)
    {
        parent::__construct($route, $pattern);

        if (is_array($route))
        {
            foreach (array('urlSuffix', 'caseSensitive', 'defaultParams', 'matchValue', 'verb', 'parsingOnly') as $name)
            {
                if (isset($route[$name]))
                    $this->$name = $route[$name];
            }
            if (isset($route['pattern']))
                $pattern = $route['pattern'];
            $route   = $route[0];
        }

        $this->route = trim($route, '/');

        $tr2['/'] = $tr['/']  = '\\/';

        if (strpos($route, '<') !== false && preg_match_all('/<(\w+)>/', $route, $matches2))
        {
            foreach ($matches2[1] as $name)
                $this->references[$name] = "<$name>";
        }

        $this->hasHostInfo = !strncasecmp($pattern, 'http://', 7) || !strncasecmp($pattern, 'https://', 8);

        if ($this->verb !== null)
            $this->verb = preg_split('/[\s,]+/', strtoupper($this->verb), -1, PREG_SPLIT_NO_EMPTY);

        // Get languages from db
        $langs = Yii::app()->db->createCommand()
                ->select('shortname, longname')
                ->from($this->langTable)
                ->queryAll();

        $shortName = array();
        if ($langs)
        {
            foreach ($langs as $lang)
            {
                $shortName[] = $lang['shortname'];
            }
        }
        // Create language string
        if (!empty($shortName))
        {
            $shortName = implode('|', $shortName);
        }
        else
        {
            $shortName = Yii::app()->language;
        }

        if (preg_match_all('/<(\w+):?(.*?)?>/', $pattern, $matches))
        {
            // replace $langExp on data from db
            $exp           = '/\(' . $this->langExp . '\)/';
            $lanPattern    = preg_replace($exp, $shortName, $matches[2][0]);
            $matches[2][0] = '(' . $lanPattern . ')';

            $tokens = array_combine($matches[1], $matches[2]);

            foreach ($tokens as $name => $value)
            {
                if ($value === '')
                    $value               = '[^\/]+';
                $tr["<$name>"]       = "(?P<$name>$value)";
                if (isset($this->references[$name]))
                    $tr2["<$name>"]      = $tr["<$name>"];
                else
                    $this->params[$name] = $value;
            }
        }

        $p              = rtrim($pattern, '*');
        $this->append   = $p !== $pattern;
        $p              = trim($p, '/');
        $this->template = preg_replace('/<(\w+):?.*?>/', '<$1>', $p);

        $this->pattern = '/^' . strtr($this->template, $tr) . '\/';
        if ($this->append)
            $this->pattern.='/u';
        else
            $this->pattern.='$/u';

        if ($this->references !== array())
            $this->routePattern = '/^' . strtr($this->route, $tr2) . '$/u';

        if (YII_DEBUG && @preg_match($this->pattern, 'test') === false)
            throw new CException(Yii::t('yii', 'The URL pattern "{pattern}" for route "{route}" is not a valid regular expression.', array('{route}' => $route, '{pattern}' => $pattern)));
    }

}
